﻿using System;
using System.Collections.Generic;
using System.Linq;
using NHibernate;
using NHibernate.Linq;
using StructureMap;
using TimeTracker.Core.Domain;
using TimeTracker.Core.Domain.Entities;
using TimeTracker.Core.Domain.Enums;

namespace TimeTracker.Core.DataAccess.Implementation
{
    [Pluggable("Default")]
    public class UnosVremenaRepository : RepositoryBase, IUnosVremenaRepository
    {
        public IList<UnosVremena> UzmiUnoseVremenaPoRadnikId(int radnikId)
        {
            var vremenaZaRadnika = (from vremena in NHibernateSession.Linq<UnosVremena>()
                                    where vremena.Radnik.RadnikId == radnikId
                                    select vremena).ToList();

            return vremenaZaRadnika;
        }

        public UnosVremena UzmiUnosVremenaPoRadnikIdZaDatum(int radnikId, DateTime dan)
        {
            var vremeZaRadnika = (from vremena in NHibernateSession.Linq<UnosVremena>()
                                  where vremena.Radnik.RadnikId == radnikId && vremena.UnosVremenaDatum == dan
                                  select vremena).SingleOrDefault();

            return vremeZaRadnika;
        }

        public void DodajPosebneSateRadnikuZaDan(int radnikId, DateTime datum, int brojSati, string tipDana, string tipSata)
        {
            var dan = (from dani in NHibernateSession.Linq<UnosVremena>()
                       where dani.Radnik.RadnikId == radnikId && dani.UnosVremenaDatum == datum
                       select dani).SingleOrDefault();

            var satZaDodati = new UnosVremenaSati();
            satZaDodati.BrojSati = brojSati;
            satZaDodati.TipSata = tipSata;
            satZaDodati.UnosVremena = dan;

            using(ITransaction transaction = NHibernateSession.BeginTransaction())
            {
                try
                {
                    NHibernateSession.SaveOrUpdate(satZaDodati);
                    transaction.Commit();
                }
                catch(Exception ex)
                {
                    transaction.Rollback();
                    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
                }
            }
        }

        public void DodajIliIzmeniDanZaRadnika(int radnikId, DateTime datum, int trajanje, string opis, string tipDana)
        {
            var danPostoji = (from dani in NHibernateSession.Linq<UnosVremena>()
                              where dani.Radnik.RadnikId == radnikId && dani.UnosVremenaDatum == datum
                              select dani).SingleOrDefault();

            if (danPostoji == null)
            {
                var danZaDodati = new UnosVremena();
                danZaDodati.Radnik.RadnikId = radnikId;
                danZaDodati.UnosVremenaDatum = datum;
                danZaDodati.UnosVremenaNapravioKorisnikId = 1;
                danZaDodati.UnosVremenaOpis = opis;
                danZaDodati.UnosVremenaTipDana = tipDana;

                NHibernateSession.SaveOrUpdate(danZaDodati);

                var satZaDodati = new UnosVremenaSati();
                satZaDodati.BrojSati = trajanje;

                if (tipDana != Utils.DataUtils.NapraviStringOdEnumZaDane(TipDana.RadniDan))
                {
                    satZaDodati.TipSata = "";
                    satZaDodati.BrojSati = 0;
                }
                else
                {
                    satZaDodati.TipSata = Utils.DataUtils.NapraviStringOdEnumZaSate(TipSata.RedovniSati);
                    satZaDodati.BrojSati = 8;
                }

                satZaDodati.UnosVremena = danZaDodati;

                NHibernateSession.SaveOrUpdate(satZaDodati);

                using (ITransaction transaction = NHibernateSession.BeginTransaction())
                {
                    try
                    {
                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
                    }
                }

                return;

            }

            var satiVremena = (from sati in NHibernateSession.Linq<UnosVremenaSati>()
                       where sati.UnosVremena.UnosVremenaId == danPostoji.UnosVremenaId
                       && sati.UnosVremena.UnosVremenaDatum == datum
                       select sati).ToList();

            foreach (UnosVremenaSati orphanSati in satiVremena)
            {
                NHibernateSession.Delete(orphanSati);
            }

            danPostoji.UnosVremenaDatum = datum;
            danPostoji.UnosVremenaOpis = opis;
            danPostoji.UnosVremenaNapravioKorisnikId = 1;
            danPostoji.UnosVremenaTipDana = tipDana;

            var sat = new UnosVremenaSati();

            sat.UnosVremena = danPostoji;

            if(tipDana != Utils.DataUtils.NapraviStringOdEnumZaDane(TipDana.RadniDan))
            {
                sat.TipSata = "";
                sat.BrojSati = 0;
            }
            else
            {
                sat.TipSata = Utils.DataUtils.NapraviStringOdEnumZaSate(TipSata.RedovniSati);
                sat.BrojSati = trajanje;
            }
            

            NHibernateSession.SaveOrUpdate(sat);

            using (ITransaction transaction = NHibernateSession.BeginTransaction())
            {
                try
                {
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
                }
            }

        }

        public IList<UnosVremenaSati> SelektujSveDaneMesecaZaRadnika(int radnikId, int year, int month)
        {
            IList<UnosVremenaSati> vremenaList = new List<UnosVremenaSati>();

            using (ITransaction transaction = NHibernateSession.BeginTransaction())
            {
                var danaUMesecu = DateTime.DaysInMonth(year, month);

                for (int dan = 1; dan < danaUMesecu; dan++)
                {
                    var vremeZaUneti = new DateTime(year, month, dan);

                    if (vremeZaUneti > DateTime.Now)
                        break;

                    if (vremeZaUneti.DayOfWeek == DayOfWeek.Saturday)
                        continue;
                    if (vremeZaUneti.DayOfWeek == DayOfWeek.Sunday)
                        continue;

                    var unosVremena = new UnosVremena();
                    unosVremena.Radnik.RadnikId = radnikId;
                    unosVremena.UnosVremenaDatum = vremeZaUneti;
                    unosVremena.UnosVremenaOpis = "Default";
                    unosVremena.UnosVremenaTipDana = "Radni dan";
                    unosVremena.UnosVremenaNapravioKorisnikId = 1;

                    NHibernateSession.SaveOrUpdate(unosVremena);

                    var unosVremenaSati = new UnosVremenaSati();
                    unosVremenaSati.BrojSati = 8;
                    unosVremenaSati.TipSata = "Redovni sati";
                    unosVremenaSati.UnosVremena = unosVremena;
                        
                    NHibernateSession.SaveOrUpdate(unosVremenaSati);

                    vremenaList.Add(unosVremenaSati);
                }

                try
                {
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
                }
            }

            return vremenaList;
        }

        public IList<UnosVremenaSati> DeselektujSveDaneMesecaZaRadnika(int radnikId, int year, int month)
        {
            IList<UnosVremenaSati> satiList = new List<UnosVremenaSati>();

            using (ITransaction transaction = NHibernateSession.BeginTransaction())
            {
                var danaUMesecu = DateTime.DaysInMonth(year, month);

                for (int dan = 1; dan < danaUMesecu; dan++)
                {
                    var vremeZaObrisati = new DateTime(year, month, dan);

                    if (vremeZaObrisati > DateTime.Now)
                        break;

                    if (vremeZaObrisati.DayOfWeek == DayOfWeek.Saturday)
                        continue;

                    if (vremeZaObrisati.DayOfWeek == DayOfWeek.Sunday)
                        continue;

                    var danZaObrisati = (from vremena in NHibernateSession.Linq<UnosVremena>()
                                         where vremena.Radnik.RadnikId == radnikId
                                               && vremena.UnosVremenaDatum == vremeZaObrisati
                                         select vremena).SingleOrDefault();

                    if(danZaObrisati == null)
                        continue;
                    
                    var satiZaObrisati = (from sati in NHibernateSession.Linq<UnosVremenaSati>()
                                          where sati.UnosVremena.UnosVremenaId == danZaObrisati.UnosVremenaId
                                          select sati).ToList();


                    foreach (UnosVremenaSati sat in satiZaObrisati)
                    {
                        satiList.Add(sat);
                        NHibernateSession.Delete(sat);
                    }

                    NHibernateSession.Delete(danZaObrisati);

                }

                try
                {
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
                }
            }

            return satiList;
        }

    }
}